<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="Hexo, NexT" />










<meta name="description" content="凡心所向，素履所往，生如逆旅，一苇以航">
<meta property="og:type" content="website">
<meta property="og:title" content="小蜗学习之旅">
<meta property="og:url" content="http://yoursite.com/index.html">
<meta property="og:site_name" content="小蜗学习之旅">
<meta property="og:description" content="凡心所向，素履所往，生如逆旅，一苇以航">
<meta property="article:author" content="小蜗">
<meta property="article:tag" content="JAVA基础">
<meta name="twitter:card" content="summary">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://yoursite.com/"/>





  <title>小蜗学习之旅</title>
  








<meta name="generator" content="Hexo 4.2.1"></head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left 
  page-home">
    <div class="headband"></div>	
	<a href="https://github.com/xiaoawo" target="_blank" rel="noopener" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
	<a href="https://github.com/xiaoawo" target="_blank" rel="noopener" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">小蜗学习之旅</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/home" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-schedule">
          <a href="/schedule/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-calendar"></i> <br />
            
            日程表
          </a>
        </li>
      
        
        <li class="menu-item menu-item-sitemap">
          <a href="/sitemap.xml" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-sitemap"></i> <br />
            
            站点地图
          </a>
        </li>
      
        
        <li class="menu-item menu-item-commonweal">
          <a href="/404/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-heartbeat"></i> <br />
            
            公益404
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            
  <section id="posts" class="posts-expand">
    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/05/31/%E5%BE%85%E5%81%9A/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="小蜗">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/xiaoawo.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="小蜗学习之旅">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2020/05/31/%E5%BE%85%E5%81%9A/" itemprop="url">待做</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-05-31T21:19:30+08:00">
                2020-05-31
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h4 id="1、手写BIO的Socket编程、BIO和NIO的区别"><a href="#1、手写BIO的Socket编程、BIO和NIO的区别" class="headerlink" title="1、手写BIO的Socket编程、BIO和NIO的区别"></a>1、手写BIO的Socket编程、BIO和NIO的区别</h4><h4 id="2、Netty线程模型、零拷贝、粘包拆包、心跳机制、Pipeline源码"><a href="#2、Netty线程模型、零拷贝、粘包拆包、心跳机制、Pipeline源码" class="headerlink" title="2、Netty线程模型、零拷贝、粘包拆包、心跳机制、Pipeline源码"></a>2、Netty线程模型、零拷贝、粘包拆包、心跳机制、Pipeline源码</h4>
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/05/31/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B-AQS/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="小蜗">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/xiaoawo.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="小蜗学习之旅">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2020/05/31/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B-AQS/" itemprop="url">JAVA多线程-AQS</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-05-31T14:37:59+08:00">
                2020-05-31
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B/" itemprop="url" rel="index">
                    <span itemprop="name">-JAVA多线程</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="AQS"><a href="#AQS" class="headerlink" title="AQS"></a>AQS</h2><p><strong>一个类的源码分析，主要就是看 继承关系、成员变量、构造方法、主要方法 这四个</strong></p>
<h3 id="一、继承关系"><a href="#一、继承关系" class="headerlink" title="一、继承关系"></a>一、继承关系</h3><pre><code>public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable</code></pre><ul>
<li>AbstractOwnableSynchronizer：用来设置和获取锁的持有者<ul>
<li>setExclusiveOwnerThread(Thread)</li>
<li>getExclusiveOwnerThread</li>
</ul>
</li>
</ul>
<h3 id="二、成员变量"><a href="#二、成员变量" class="headerlink" title="二、成员变量"></a>二、成员变量</h3><pre><code>static final class Node {

    static final Node EXCLUSIVE = null;

    static final int PROPAGATE = -3;

    volatile int waitStatus;

    volatile Node prev;

    volatile Node next;

    volatile Thread thread;

    Node nextWaiter;


    final boolean isShared() {
        return nextWaiter == SHARED;
    }


    final Node predecessor() throws NullPointerException {
        Node p = prev;
        if (p == null)
            throw new NullPointerException();
        else
            return p;
    }

    Node() {    // Used to establish initial head or SHARED marker
    }

    Node(Thread thread, Node mode) {     // Used by addWaiter
        this.nextWaiter = mode;
        this.thread = thread;
    }

    Node(Thread thread, int waitStatus) { // Used by Condition
        this.waitStatus = waitStatus;
        this.thread = thread;
    }
}</code></pre><h3 id="三、构造方法"><a href="#三、构造方法" class="headerlink" title="三、构造方法"></a>三、构造方法</h3><h3 id="四、主要方法"><a href="#四、主要方法" class="headerlink" title="四、主要方法"></a>四、主要方法</h3>
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/05/29/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B-ReentrantLock/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="小蜗">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/xiaoawo.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="小蜗学习之旅">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2020/05/29/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B-ReentrantLock/" itemprop="url">JAVA多线程-ReentrantLock</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-05-29T22:34:14+08:00">
                2020-05-29
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B/" itemprop="url" rel="index">
                    <span itemprop="name">-JAVA多线程</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="ReentrantLock"><a href="#ReentrantLock" class="headerlink" title="ReentrantLock"></a>ReentrantLock</h2><p><strong>一个类的源码分析，主要就是看 继承关系、成员变量、构造方法、主要方法 这四个</strong></p>
<h3 id="一、继承关系"><a href="#一、继承关系" class="headerlink" title="一、继承关系"></a>一、继承关系</h3><pre><code>public class ReentrantLock implements Lock, java.io.Serializable</code></pre><p>只实现了两个接口：Lock 和 java.io.Serializable</p>
<h3 id="二、成员变量"><a href="#二、成员变量" class="headerlink" title="二、成员变量"></a>二、成员变量</h3><pre><code>private final Sync sync;</code></pre><p>只有一个同步器，但是定义了三个内部类：  </p>
<ul>
<li>abstract static class Sync extends AbstractQueuedSynchronizer</li>
<li>static final class NonfairSync extends Sync</li>
<li>static final class FairSync extends Sync</li>
</ul>
<p>可以看到，Sync只是一个继承了AQS的抽象同步器，真正的实现是：NonfairSync 和 FairSync</p>
<h4 id="1、Sync的具体实现"><a href="#1、Sync的具体实现" class="headerlink" title="1、Sync的具体实现"></a>1、Sync的具体实现</h4><pre><code>abstract static class Sync extends AbstractQueuedSynchronizer {
    private static final long serialVersionUID = -5179523762034025860L;//不用管

    abstract void lock();//具体实现有子类来做

    final boolean nonfairTryAcquire(int acquires) {//非公平的尝试获取锁
        final Thread current = Thread.currentThread();
        int c = getState();//AQS的方法，返回当前的state（当前被持有的次数）
        if (c == 0) {//state未被任何线程持有
            if (compareAndSetState(0, acquires)) {//AQS的方法，使用CAS获取锁
                setExclusiveOwnerThread(current);//Exclusive：独享的
                return true;
            }
        }else if (current == getExclusiveOwnerThread()) {//判断持有锁的线程是否为当前线程，是，则重入
            int nextc = c + acquires;
            if (nextc &lt; 0) // overflow
                throw new Error(&quot;Maximum lock count exceeded&quot;);
            setState(nextc);
            return true;
        }
        return false;
    }

    protected final boolean tryRelease(int releases) {//尝试释放锁
        int c = getState() - releases;
        if (Thread.currentThread() != getExclusiveOwnerThread())//当前线程没有持有锁时会抛出异常
            throw new IllegalMonitorStateException();
        boolean free = false;
        if (c == 0) {
            free = true;
            setExclusiveOwnerThread(null);//设置锁的持有者为null
        }
        setState(c);//重置state
        return free;
    }

    //判断当前是否是锁的持有者
    protected final boolean isHeldExclusively() {
        // While we must in general read state before owner,
        // we don&apos;t need to do so to check if current thread is owner
        return getExclusiveOwnerThread() == Thread.currentThread();
    }

    //新建Condition
    final ConditionObject newCondition() {
        return new ConditionObject();
    }

    //获取线程的持有者
    final Thread getOwner() {
        return getState() == 0 ? null : getExclusiveOwnerThread();
    }

    //获取锁被持有的次数（state）
    final int getHoldCount() {
        return isHeldExclusively() ? getState() : 0;
    }

    //判断是否上锁了
    final boolean isLocked() {
        return getState() != 0;
    }

    /**
     * Reconstitutes the instance from a stream (that is, deserializes it).
     */
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        s.defaultReadObject();
        setState(0); // reset to unlocked state
    }
}</code></pre><p>final boolean nonfairTryAcquire(int acquires) :</p>
<div id="flowchart-0" class="flow-chart"></div>

<p>protected final boolean tryRelease(int releases)</p>
<div id="flowchart-1" class="flow-chart"></div>


<p>所以，sync里就两个主要的方法：一个是非公平的尝试获取锁，另一个就是尝试进行一次锁的释放</p>
<p>再看非公平和公平的实现方式</p>
<h4 id="2、NonfairSync的具体实现"><a href="#2、NonfairSync的具体实现" class="headerlink" title="2、NonfairSync的具体实现"></a>2、NonfairSync的具体实现</h4><pre><code>static final class NonfairSync extends Sync {
    private static final long serialVersionUID = 7316153563782823691L;

    //实现了lock
    final void lock() {
        if (compareAndSetState(0, 1))//使用CAS尝试一次获取锁
            setExclusiveOwnerThread(Thread.currentThread());
        else
            acquire(1);//AQS的方法【获锁失败了，就添加到队列中】
    }

    protected final boolean tryAcquire(int acquires) {
        return nonfairTryAcquire(acquires);
    }
}</code></pre><h4 id="3、FairSync的具体实现"><a href="#3、FairSync的具体实现" class="headerlink" title="3、FairSync的具体实现"></a>3、FairSync的具体实现</h4><pre><code>static final class FairSync extends Sync {
    private static final long serialVersionUID = -3000897897090466540L;

    final void lock() {
        acquire(1);
    }

    /**
     * Fair version of tryAcquire.  Don&apos;t grant access unless
     * recursive call or no waiters or is first.
     */
    protected final boolean tryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        if (c == 0) {
            if (!hasQueuedPredecessors() &amp;&amp; compareAndSetState(0, acquires)) {//只比非公平的方式多了一个hasQueuedPredecessors()判断（是否为队列的头）
                setExclusiveOwnerThread(current);
                return true;
            }
        }else if (current == getExclusiveOwnerThread()) {
            int nextc = c + acquires;
            if (nextc &lt; 0)
                throw new Error(&quot;Maximum lock count exceeded&quot;);
            setState(nextc);
            return true;
        }
        return false;
    }
}</code></pre><p>protected final boolean tryAcquire(int acquires)</p>
<div id="flowchart-2" class="flow-chart"></div>

<h4 id="4、小结"><a href="#4、小结" class="headerlink" title="4、小结"></a>4、小结</h4><ul>
<li>锁释放，对公平和非公平而言貌似没有区别，所以在sync中实现了tryRelease,同时sync里也实现了非公平的获取锁的方法nonfairTryAcquire</li>
<li>对于公平锁和非公平锁而言，其实仅有两处代码上的不同<ul>
<li>lock()：非公平先进行了一次CAS加锁</li>
<li>tryAcquire()：公平锁需要进行一次是否为队列头节点的判断</li>
</ul>
</li>
</ul>
<h3 id="三、构造方法"><a href="#三、构造方法" class="headerlink" title="三、构造方法"></a>三、构造方法</h3><p>就两个，本质上就是返回NonfairSync或FairSync的实例，默认为NonfairSync</p>
<pre><code>public ReentrantLock() {
    sync = new NonfairSync();
}

public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}</code></pre><h3 id="四、主要方法"><a href="#四、主要方法" class="headerlink" title="四、主要方法"></a>四、主要方法</h3><h4 id="1、lock"><a href="#1、lock" class="headerlink" title="1、lock"></a>1、lock</h4><pre><code>public void lock() {
    sync.lock();
}</code></pre><h4 id="2、unlock"><a href="#2、unlock" class="headerlink" title="2、unlock"></a>2、unlock</h4><pre><code>public void unlock() {//AQS的方法，但是tryRelease的具体实现，又由具体实例来做的，就是上面分析那些
    sync.release(1);
}&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.7/raphael.min.js&quot;&gt;&lt;/script&gt;&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/flowchart/1.6.5/flowchart.min.js&quot;&gt;&lt;/script&gt;{% raw %}<textarea id="flowchart-0-code" style="display: none">st=>start: Start
op1=>operation: 获取当前线程
op2=>operation: 获取state

cond2=>condition: 使用CAS让当前线程持有锁

cond3=>condition: 当前线程是否已经持有锁了

cond1=>condition: state==0 ?

op3=>operation: 重置state


e1=>end: return true
e2=>end: return false
e3=>end: return false
st->op1->op2->cond1
cond1(yes)->cond2
cond1(no)->cond3
cond2(yes)->e1
cond2(no)->e2
cond3(yes)->op3->e1
cond3(no)->e3</textarea><textarea id="flowchart-0-options" style="display: none">{"scale":1,"line-width":2,"line-length":50,"text-margin":10,"font-size":12}</textarea><script>  var code = document.getElementById("flowchart-0-code").value;  var options = JSON.parse(decodeURIComponent(document.getElementById("flowchart-0-options").value));  var diagram = flowchart.parse(code);  diagram.drawSVG("flowchart-0", options);</script>{% endraw %}{% raw %}<textarea id="flowchart-1-code" style="display: none">st=>start: Start
cond1=>condition: 判断当前线程是否持有锁

op0=>operation: boolean free = false
cond2=>condition: state==0?

op3=>operation: free = true
op1=>operation: 设置锁的持有者为null
op2=>operation: 重置state


e=>end: return free
op4=>operation: 抛出异常

st->cond1
cond1(yes)->op0->cond2
cond1(no)->op4

cond2(yes)->op3->op1->e
cond2(no)->e</textarea><textarea id="flowchart-1-options" style="display: none">{"scale":1,"line-width":2,"line-length":50,"text-margin":10,"font-size":12}</textarea><script>  var code = document.getElementById("flowchart-1-code").value;  var options = JSON.parse(decodeURIComponent(document.getElementById("flowchart-1-options").value));  var diagram = flowchart.parse(code);  diagram.drawSVG("flowchart-1", options);</script>{% endraw %}{% raw %}<textarea id="flowchart-2-code" style="display: none">st=>start: Start
op1=>operation: 获取当前线程
op2=>operation: 获取state

cond1=>condition: state==0 ?

cond2=>condition: 是否是头节点&&CAS获锁成功

cond3=>condition: 当前线程是否已经持有锁了



op3=>operation: 重置state


e1=>end: return true
e2=>end: return false
e3=>end: return false
st->op1->op2->cond1
cond1(yes)->cond2
cond1(no)->cond3
cond2(yes)->e1
cond2(no)->e2
cond3(yes)->op3->e1
cond3(no)->e3</textarea><textarea id="flowchart-2-options" style="display: none">{"scale":1,"line-width":2,"line-length":50,"text-margin":10,"font-size":12}</textarea><script>  var code = document.getElementById("flowchart-2-code").value;  var options = JSON.parse(decodeURIComponent(document.getElementById("flowchart-2-options").value));  var diagram = flowchart.parse(code);  diagram.drawSVG("flowchart-2", options);</script>{% endraw %}</code></pre>
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/05/29/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B-%E5%8E%9F%E5%AD%90%E7%B1%BB/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="小蜗">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/xiaoawo.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="小蜗学习之旅">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2020/05/29/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B-%E5%8E%9F%E5%AD%90%E7%B1%BB/" itemprop="url">JAVA多线程-原子类</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-05-29T19:02:24+08:00">
                2020-05-29
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B/" itemprop="url" rel="index">
                    <span itemprop="name">-JAVA多线程</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="原子类"><a href="#原子类" class="headerlink" title="原子类"></a>原子类</h2><h3 id="一、AtomicInteger"><a href="#一、AtomicInteger" class="headerlink" title="一、AtomicInteger"></a>一、AtomicInteger</h3><p>先看这个</p>
<pre><code>private static final Unsafe unsafe = Unsafe.getUnsafe();//unsafe的来源（这是一个static变量，在类加载完成后就存在了）
private static final long valueOffset;（通过下面的静态代码块完成初始化）

static {
    try {
        //先根据反射拿到AtomicInteger.class中的&quot;value&quot;对应的Field，然后根据这个Field生成valueOffset
        //objectFieldOffset是一个native方法
        //valueOffset应该是value在AtomicInteger的偏移量（方便快速读取）
        valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField(&quot;value&quot;));
    } catch (Exception ex) { throw new Error(ex); }
}</code></pre><p>在类加载时，会生成一个unsafe，同时得到value在对象中的偏移量（方便快速读取）</p>
<h4 id="1、构造函数"><a href="#1、构造函数" class="headerlink" title="1、构造函数"></a>1、构造函数</h4><pre><code>public AtomicInteger(int initialValue) {
    value = initialValue;//private volatile int value;内部通过一个volatile变量来保存
}</code></pre><p>很简单，直接给 volatile int value 赋值即可</p>
<h4 id="2、加法函数"><a href="#2、加法函数" class="headerlink" title="2、加法函数"></a>2、加法函数</h4><pre><code>public final int addAndGet(int delta) {
    //也就是说加的操作实际是由unsafe.getAndAddInt(this, valueOffset, delta)完成的
    return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
}


#################### unsafe.getAndAddInt(this, valueOffset, delta) #######################

public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        //native，根据AtomicInteger对向本身和value在AtomicInteger的偏移量得到value的值
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));//native，执行CAS

    return var5;
}</code></pre><p>其实就两步，先获取旧值，然后使用CAS更新新值</p>
<h4 id="3、补充"><a href="#3、补充" class="headerlink" title="3、补充"></a>3、补充</h4><ul>
<li><a href="https://www.cnblogs.com/pkufork/p/java_unsafe.html" target="_blank" rel="noopener"><strong>Unsafe</strong></a></li>
<li><strong>CAS缺点</strong><ul>
<li>ABA问题：使用版本号解决  </li>
<li>不成功，则一直循环，会造成CPU资源浪费：限定循环次数</li>
</ul>
</li>
</ul>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/05/29/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B-%E7%BA%BF%E7%A8%8B%E9%97%B4%E9%80%9A%E4%BF%A1/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="小蜗">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/xiaoawo.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="小蜗学习之旅">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2020/05/29/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B-%E7%BA%BF%E7%A8%8B%E9%97%B4%E9%80%9A%E4%BF%A1/" itemprop="url">JAVA多线程-线程间通信</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-05-29T15:15:39+08:00">
                2020-05-29
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/JAVA%E5%A4%9A%E7%BA%BF%E7%A8%8B/" itemprop="url" rel="index">
                    <span itemprop="name">-JAVA多线程</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="线程间通信"><a href="#线程间通信" class="headerlink" title="线程间通信"></a>线程间通信</h2><h3 id="一、ThreadLocal"><a href="#一、ThreadLocal" class="headerlink" title="一、ThreadLocal"></a>一、ThreadLocal</h3><h4 id="1、原理介绍"><a href="#1、原理介绍" class="headerlink" title="1、原理介绍"></a>1、原理介绍</h4><ul>
<li>如果一个变量在线程运行的很长时间内均需要，且在多个类，方法中出现，此时可考虑使用ThreadLocal绑定该变量</li>
<li><a href="https://blog.csdn.net/puppylpg/article/details/80433271" target="_blank" rel="noopener"><strong>ThreadLocal原理及内存泄露预防</strong></a></li>
</ul>
<h4 id="2、源码分析"><a href="#2、源码分析" class="headerlink" title="2、源码分析"></a>2、源码分析</h4><ul>
<li><p>set(V)  </p>
<pre><code>public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);//获取当前线程的ThreadLocalMap
    if (map != null)
        map.set(this, value);//线性探测解决hash冲突
    else
        createMap(t, value);
}

############# getMap(Thread t) ################

ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;//ThreadLocal.ThreadLocalMap threadLocals = null;
}

############# createMap(Thread, T) ################

void createMap(Thread t, T firstValue) {
    t.threadLocals = new ThreadLocalMap(this, firstValue);
}</code></pre></li>
<li><p>get() </p>
<pre><code>public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings(&quot;unchecked&quot;)
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();//map不存在时，返回初始值
}

############# getEntry(ThreadLocal&lt;?&gt; key) ################

private Entry getEntry(ThreadLocal&lt;?&gt; key) {
    int i = key.threadLocalHashCode &amp; (table.length - 1);//计算索引
    Entry e = table[i];
    if (e != null &amp;&amp; e.get() == key)
        return e;
    else
        return getEntryAfterMiss(key, i, e);//线性探测
}

############# getEntryAfterMiss(ThreadLocal&lt;?&gt; key, int i, Entry e) ################

private Entry getEntryAfterMiss(ThreadLocal&lt;?&gt; key, int i, Entry e) {
    Entry[] tab = table;
    int len = tab.length;

    while (e != null) {
        ThreadLocal&lt;?&gt; k = e.get();
        if (k == key)
            return e;
        if (k == null)
            expungeStaleEntry(i);//详细的不再分析，主要作用就是，清除那些key为null,但value不为null的Entry(否则会引起内存泄漏)
        else
            i = nextIndex(i, len);
        e = tab[i];
    }
    return null;
}</code></pre></li>
</ul>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/05/29/JVM-%E8%B0%83%E4%BC%98/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="小蜗">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/xiaoawo.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="小蜗学习之旅">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2020/05/29/JVM-%E8%B0%83%E4%BC%98/" itemprop="url">JVM-调优</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-05-29T12:53:04+08:00">
                2020-05-29
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/JVM/" itemprop="url" rel="index">
                    <span itemprop="name">-JVM</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="JVM调优"><a href="#JVM调优" class="headerlink" title="JVM调优"></a>JVM调优</h2><h3 id="一、JVM参数配置"><a href="#一、JVM参数配置" class="headerlink" title="一、JVM参数配置"></a>一、JVM参数配置</h3><div align=center><img src="https://img-blog.csdnimg.cn/2018120320461094.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDMyMTY3Mg==,size_16,color_FFFFFF,t_70" width="600"/></div>

<div align=center>JVM内存模型</div>


<ul>
<li><strong>方法区</strong>：主要用来存放Class对象、常量。。。所以不会很占空间</li>
<li><strong>堆</strong>：涉及到对象频繁的创建与销毁，因此分为了新生代和老年代<ul>
<li>新生代：采用复制算法，一般From Survivor：To Survivor：Eden = 1:1:8</li>
<li>老年代：新生代/老年代=3/8</li>
</ul>
</li>
<li><strong>程序计数器</strong>：不会占很大空间，不需要关注</li>
<li><strong>方法栈（虚拟机栈和本地方法栈）</strong>：主要是栈的深度占空间，而且一旦栈大了，那么可分配的线程数就会减少</li>
</ul>
<h4 id="1、堆设置"><a href="#1、堆设置" class="headerlink" title="1、堆设置"></a>1、堆设置</h4><ul>
<li>-Xms:初始堆大小  </li>
<li>-Xmx:最大堆大小<br>【一般-Xms和-Xmx设置相同，同时如果非Java程序较少，可尽量接近OS的实际内存】 </li>
<li>-XX:NewSize=n:设置年轻代大小  </li>
<li>-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3，表示年轻代与年老代比值为1：3，年轻代占整个年轻代年老代和的1/4  </li>
<li>-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如：3，表示Eden：Survivor=3：2，一个Survivor区占整个年轻代的1/5  </li>
<li>-XX:MaxPermSize=n:设置持久代大小</li>
<li>-XX:MaxTenuringThreshold=0：设置垃圾最大年龄。  超过该年龄的对象进入老年代<br>【新生代、老年代、永久代实际上应该根据实际的应用运行情况来设置,一般建议：新/老=3/8；永久代=64m 】</li>
</ul>
<h4 id="2、栈设置"><a href="#2、栈设置" class="headerlink" title="2、栈设置"></a>2、栈设置</h4><ul>
<li>-Xss128k： 设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M，以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下，减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的，不能无限生成，经验值在3000~5000左右。</li>
</ul>
<h4 id="3、收集器设置"><a href="#3、收集器设置" class="headerlink" title="3、收集器设置"></a>3、收集器设置</h4><ul>
<li>-XX:+UseSerialGC:设置串行收集器  </li>
<li>-XX:+UseParallelGC:设置并行收集器  </li>
<li>-XX:+UseParalledlOldGC:设置并行年老代收集器  <ul>
<li>-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。</li>
<li>-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间</li>
<li>-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)</li>
</ul>
</li>
<li>-XX:+UseConcMarkSweepGC:设置并发收集器  <ul>
<li>-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。</li>
<li>-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时，使用的CPU数。并行收集线程数。</li>
<li>-XX:CMSFullGCsBeforeCompaction=n：由于并发收集器不对内存空间进行压缩、整理，所以运行一段时间以后会产生“碎片”，使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。</li>
<li>-XX:+UseCMSCompactAtFullCollection：打开对年老代的压缩。可能会影响性能，但是可以消除碎片</li>
</ul>
</li>
</ul>
<h4 id="4、垃圾回收统计信息"><a href="#4、垃圾回收统计信息" class="headerlink" title="4、垃圾回收统计信息"></a>4、垃圾回收统计信息</h4><ul>
<li>-XX:+PrintGC</li>
<li>-XX:+PrintGCDetails</li>
<li>-XX:+PrintGCTimeStamps</li>
<li>-XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前，程序未中断的执行时间</li>
<li>-XX:+PrintGCApplicationStoppedTime：打印垃圾回收期间程序暂停的时间</li>
<li>-Xloggc:filename</li>
</ul>
<h4 id="5、调优总结"><a href="#5、调优总结" class="headerlink" title="5、调优总结"></a>5、调优总结</h4><p><strong>年轻代大小选择</strong>  </p>
<ul>
<li>响应时间优先的应用：尽可能设大，直到接近系统的最低响应时间限制（根据实际情况选择）。在此种情况下，年轻代收集发生的频率也是最小的。同时，减少到达年老代的对象。  </li>
<li>吞吐量优先的应用：尽可能的设置大，可能到达Gbit的程度。因为对响应时间没有要求，垃圾收集可以并行进行，一般适合8CPU以上的应用。</li>
</ul>
<p><strong>老年代大小选择</strong> </p>
<ul>
<li>响应时间优先的应用：年老代使用并发收集器，所以其大小需要小心设置，一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了，可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式；如果堆大了，则需要较长的收集时间。最优化的方案，一般需要参考以下数据获得： <ul>
<li>并发垃圾收集信息  </li>
<li>持久代并发收集次数  </li>
<li>传统GC信息  </li>
<li>花在年轻代和年老代回收上的时间比例    </li>
<li>减少年轻代和年老代花费的时间，一般会提高应用的效率  </li>
</ul>
</li>
<li>吞吐量优先的应用：一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。原因是，这样可以尽可能回收掉大部分短期对象，减少中期的对象，而年老代尽存放长期存活对象。  </li>
</ul>
<p><strong>较小堆引起的碎片问题</strong>  </p>
<p>因为年老代的并发收集器使用标记、清除算法，所以不会对堆进行压缩。当收集器回收时，他会把相邻的空间进行合并，这样可以分配给较大的对象。但是，当堆空间较小时，运行一段时间以后，就会出现“碎片”，如果并发收集器找不到足够的空间，那么并发收集器将会停止，然后使用传统的标记、清除方式进行回收。如果出现“碎片”，可能需要进行如下配置：  </p>
<ul>
<li>-XX:+UseCMSCompactAtFullCollection：使用并发收集器时，开启对年老代的压缩。  </li>
<li>-XX:CMSFullGCsBeforeCompaction=0：上面配置开启的情况下，这里设置多少次Full GC后，对年老代进行压缩</li>
</ul>
<h4 id="6、调优实战"><a href="#6、调优实战" class="headerlink" title="6、调优实战"></a>6、调优实战</h4><ul>
<li><a href="https://www.jianshu.com/p/fa1bd3557a16" target="_blank" rel="noopener"><strong>JVM参数配置及优化</strong></a></li>
</ul>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/05/29/%E5%8F%8D%E5%B0%84%E7%9A%84%E6%A6%82%E5%BF%B5%E3%80%81%E7%94%A8%E6%B3%95/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="小蜗">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/xiaoawo.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="小蜗学习之旅">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2020/05/29/%E5%8F%8D%E5%B0%84%E7%9A%84%E6%A6%82%E5%BF%B5%E3%80%81%E7%94%A8%E6%B3%95/" itemprop="url">反射的概念、用法</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-05-29T11:48:20+08:00">
                2020-05-29
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <p><img src="https://raw.githubusercontent.com/xiaoawo/photo/master/%E5%8F%8D%E5%B0%84%EF%BC%9A%E6%8A%8A%E7%B1%BB%E5%89%96%E7%9A%84%E5%BE%88%E7%BB%86%E8%87%B4.svg" alt="11"></p>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/05/28/JVM-%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="小蜗">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/xiaoawo.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="小蜗学习之旅">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2020/05/28/JVM-%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/" itemprop="url">JVM-类加载机制</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-05-28T21:41:29+08:00">
                2020-05-28
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/JVM/" itemprop="url" rel="index">
                    <span itemprop="name">-JVM</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="类加载机制"><a href="#类加载机制" class="headerlink" title="类加载机制"></a>类加载机制</h2><h4 id="一、概述"><a href="#一、概述" class="headerlink" title="一、概述"></a>一、概述</h4><ul>
<li>在使用 java -c *.java 后，会根据 *.java这样一个文件生成一个 *.class文件（以二进制形式存在）</li>
<li>*.class包含了描述*.java的所有信息</li>
<li>但是，JVM在使用一个类时，不可能每次都根据 *.class这样一个二进制文件来处理，所以必须将 *.class转为一种方便操作的类型（Class对象）</li>
<li>将 *.class文件转为JVM内的Class对象的过程就是类加载的过程</li>
</ul>
<h4 id="二、类加载时机"><a href="#二、类加载时机" class="headerlink" title="二、类加载时机"></a>二、类加载时机</h4><p><strong>1、类加载时机并无明确规定</strong>  </p>
<p><strong>2、类初始化时机，有且只有5种（所以，类加载必须在此之前完成）</strong>  </p>
<ul>
<li>遇到new、getstatic（获取静态变量）、putstatic（设置静态变量）、invokestatic（调用静态方法）  </li>
<li>反射调用</li>
<li>初始化子类之前必先初始化父类</li>
<li>JVM启动时，会先执行一个启动类（包含main()方法的类）</li>
<li>当使用jdk1.7动态语言支持时，如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getstatic, REF_putstatic, REF_invokeStatic的方法句柄，并且这个方法句柄所对应的类没有进行初始化，则需要先出触发其初始化</li>
</ul>
<h4 id="三、类加载过程"><a href="#三、类加载过程" class="headerlink" title="三、类加载过程"></a>三、类加载过程</h4><div align=center><img src="http://static.zybuluo.com/Rico123/ojhhtids41ivtuowfj74mkb2/%E7%B1%BB%E5%8A%A0%E8%BD%BD%E8%BF%87%E7%A8%8B" width="600"/></div>

<div align=center>类的生命周期</div>

<p><strong>1、加载</strong>   </p>
<ul>
<li>根据类名寻找描述该类的二进制字节流（比如，*.class文件）的过程【这里涉及到了双亲委派模型（后面聊）】</li>
<li>将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构</li>
<li>在内存中(对于HotSpot虚拟就而言就是方法区)生成一个代表这个类的 java.lang.Class 对象，作为方法区这个类的各种数据的访问入口</li>
</ul>
<p><strong>2、验证</strong> </p>
<p>主要目的是为了防止恶意的*.class文件，保证安全，但不是必须的</p>
<ul>
<li>文件格式验证：验证字节流是否符合Class文件格式的规范(例如，是否以魔术0xCAFEBABE开头、主次版本号是否在当前虚拟机的处理范围之内、常量池中的常量是否有不被支持的类型)</li>
<li>元数据验证：对字节码描述的信息进行语义分析，以保证其描述的信息符合Java语言规范的要求(例如：这个类是否有父类，除了java.lang.Object之外)；</li>
<li>字节码验证：通过数据流和控制流分析，确定程序语义是合法的、符合逻辑的;</li>
<li>符号引用验证：确保解析动作能正确执行。</li>
</ul>
<p><strong>3、准备</strong></p>
<p> 为类变量(static 成员变量)分配内存并设置类变量初始值（零值）的阶段，这些变量所使用的内存都将在方法区中进行分配</p>
<ul>
<li>final修饰的会直接赋设置的值，而非零值</li>
</ul>
<p><strong>4、解析</strong></p>
<p>将常量池内的符号引用替换为直接引用</p>
<p><strong>5、初始化</strong></p>
<p>初始化阶段是执行类构造器<clinit>()方法的过程。  </p>
<ul>
<li>&lt;clinit&gt;()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块static{}中的语句合并产生的，编译器收集的顺序是由语句在源文件中出现的顺序所决定的，静态语句块只能访问到定义在静态语句块之前的变量，定义在它之后的变量，在前面的静态语句块可以赋值，但是不能访问。</li>
</ul>
<h4 id="四、类加载器"><a href="#四、类加载器" class="headerlink" title="四、类加载器"></a>四、类加载器</h4><p><strong>1、类加载器</strong> </p>
<ul>
<li><p>类加载器的作用就是根据类的全限定名获取描述此类的二进制字节流</p>
</li>
<li><p>在JVM通过类加载和类本身来确定类的唯一性</p>
</li>
<li><p><strong>JVM自带的加载器（重要）：</strong></p>
<ul>
<li>Bootstrap，根加载器 :  <ul>
<li>加载 jre\lib\ *.jar（包含了Object、String、Math等平时编写代码时 大部分的jdk API）；  </li>
<li>也可以通过JVM参数-Xbootclasspath指定加载某一个jar扩展类加载器</li>
</ul>
</li>
<li>Extension，扩展类加载器 ：<ul>
<li>加载jre中lib\ext\ *.jar中的类 ;</li>
<li>也可以通过JVM参数-Djava.ext.dirs指定加载某一个jar</li>
</ul>
</li>
<li>AppClassLoader/SystemClassLoader，系统加载器（也称为应用加载器）：<ul>
<li>加载classpath（通常程序中的src）；</li>
<li>也可以通过JVM参数-Djava.class.path指定加载某一个类/jar</li>
</ul>
</li>
</ul>
</li>
<li><p>用户自定义的加载器都是抽象类java.lang.ClassLoader的子类，用于自定义加载</p>
</li>
</ul>
<p><strong>2、双亲委派模型</strong> </p>
<div align=center><img src="http://www.sxkawzp.cn/upload/2019/10/ClassLoaderThree-0dcc2a754beb42b598e9fdc067822ff2.png" width="600"/></div>

<div align=center>双亲委派模型</div>

<ul>
<li><p><strong>双亲委派”机制加载Class的具体过程是：</strong>  </p>
<ul>
<li>源ClassLoader先判断该Class是否已加载，如果已加载，则返回Class对象；如果没有则委托给父类加载器。</li>
<li>父类加载器判断是否加载过该Class，如果已加载，则返回Class对象；如果没有则委托给祖父类加载器。依此类推，直到始祖类加载器（引用类加载器）。</li>
<li>始祖类加载器判断是否加载过该Class，如果已加载，则返回Class对象；如果没有则尝试从其对应的类路径下寻找class字节码文件并载入。如果载入成功，则返回Class对象；如果载入失败，则委托给始祖类加载器的子类加载器。</li>
<li>始祖类加载器的子类加载器尝试从其对应的类路径下寻找class字节码文件并载入。如果载入成功，则返回Class对象；如果载入失败，则委托给始祖类加载器的孙类加载器。依此类推，直到源ClassLoader。</li>
<li>源ClassLoader尝试从其对应的类路径下寻找class字节码文件并载入。如果载入成功，则返回Class对象；如果载入失败，源ClassLoader不会再委托其子类加载器，而是抛出异常。</li>
</ul>
</li>
<li><p>主要有了层次结构后，可以保证类的加载不再混乱，避免重复加载以及恶意代码，使得java程序可以稳定运行</p>
<pre><code>protected Class&lt;?&gt; loadClass(String name, boolean resolve) throws ClassNotFoundException{

    synchronized (getClassLoadingLock(name)) {//加锁
        // First, check if the class has already been loaded
        Class&lt;?&gt; c = findLoadedClass(name);//检查是否已经加载过了
        if (c == null) {
            long t0 = System.nanoTime();
            try {
                if (parent != null) {//父不为空，交由父加载
                    c = parent.loadClass(name, false);
                } else {//父为空，说明当前为根加载器
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {
                // ClassNotFoundException thrown if class not found
                // from the non-null parent class loader
            }

            if (c == null) {//父未加载成功，交由当前类加载完成
                // If still not found, then invoke findClass in order
                // to find the class.
                long t1 = System.nanoTime();
                c = findClass(name);

                // this is the defining class loader; record the stats
                sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                sun.misc.PerfCounter.getFindClasses().increment();
            }
        }
        if (resolve) {
            resolveClass(c);
        }
        return c;
    }
}</code></pre></li>
</ul>
<ul>
<li><p><strong>全盘委托机制</strong>  </p>
<ul>
<li>是指当一个ClassLoader装载一个类时，除非显示地使用另一个ClassLoader，则该类所依赖及引用的类也由这个CladdLoader载入。</li>
<li>例如，系统类加载器AppClassLoader加载入口类（含有main方法的类）时，会把main方法所依赖的类及引用的类也载入，依此类推。“全盘负责”机制也可称为当前类加载器负责机制。显然，入口类所依赖的类及引用的类的当前类加载器就是入口类的类加载器。</li>
<li>注意：真正加载class字节码文件生成Class对象的类加载器由“双亲委派”机制完成。  </li>
</ul>
</li>
</ul>
<ul>
<li>我们可以继承java.lang.ClassLoader类，实现自己的类加载器。如果想保持双亲委派模型，就应该重写findClass(name)方法；如果想破坏双亲委派模型，可以重写loadClass(name)方法</li>
</ul>
<p><strong>3、破坏双亲委派模型</strong></p>
<ul>
<li>继承java.lang.ClassLoader类，实现自己的类加载器,重写loadClass(name)方法</li>
<li>使用线程上下文类加载器（默认为应用类加载器）<ul>
<li><a href="https://www.sxkawzp.cn/archives/JdbcTomcatClassLoaderDestroy" target="_blank" rel="noopener">JDBC,TOMCAT为什么破坏双亲委派机制</a> </li>
</ul>
</li>
</ul>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/05/28/%E9%9D%A2%E7%BB%8F-%E4%BA%92%E8%81%94%E7%BD%91-%E4%BA%AC%E4%B8%9C/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="小蜗">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/xiaoawo.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="小蜗学习之旅">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2020/05/28/%E9%9D%A2%E7%BB%8F-%E4%BA%92%E8%81%94%E7%BD%91-%E4%BA%AC%E4%B8%9C/" itemprop="url">面经-互联网-京东</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-05-28T20:59:16+08:00">
                2020-05-28
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E9%9D%A2%E7%BB%8F-%E4%BA%92%E8%81%94%E7%BD%91-%E4%BA%AC%E4%B8%9C/" itemprop="url" rel="index">
                    <span itemprop="name">-面经 -互联网 -京东</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="面经一"><a href="#面经一" class="headerlink" title="面经一"></a>面经一</h2><h3 id="说明：说实话，看到这份面经，还是有点震惊"><a href="#说明：说实话，看到这份面经，还是有点震惊" class="headerlink" title="说明：说实话，看到这份面经，还是有点震惊"></a>说明：说实话，看到这份面经，还是有点震惊</h3><p><a href="https://www.nowcoder.com/discuss/432918" target="_blank" rel="noopener">原文链接</a></p>
<h3 id="一面（视频面）-1小时30分钟"><a href="#一面（视频面）-1小时30分钟" class="headerlink" title="一面（视频面）  1小时30分钟"></a>一面（视频面）  1小时30分钟</h3><h4 id="1、类加载机制概念、加载步骤、双亲委托机制、全盘委托机制、类加载器种类及继承关系"><a href="#1、类加载机制概念、加载步骤、双亲委托机制、全盘委托机制、类加载器种类及继承关系" class="headerlink" title="1、类加载机制概念、加载步骤、双亲委托机制、全盘委托机制、类加载器种类及继承关系"></a>1、类加载机制概念、加载步骤、双亲委托机制、全盘委托机制、类加载器种类及继承关系</h4><h4 id="2、如何实现让类加载器去加载网络上的资源文件？怎么自定义类加载器？自定义的加载器还符合双亲委托机制吗？怎么打破双亲委托机制？"><a href="#2、如何实现让类加载器去加载网络上的资源文件？怎么自定义类加载器？自定义的加载器还符合双亲委托机制吗？怎么打破双亲委托机制？" class="headerlink" title="2、如何实现让类加载器去加载网络上的资源文件？怎么自定义类加载器？自定义的加载器还符合双亲委托机制吗？怎么打破双亲委托机制？"></a>2、如何实现让类加载器去加载网络上的资源文件？怎么自定义类加载器？自定义的加载器还符合双亲委托机制吗？怎么打破双亲委托机制？</h4><ul>
<li><a href="https://xiaoawo.github.io/2020/05/28/JVM-类加载机制/" target="_blank" rel="noopener">类加载机制</a></li>
</ul>
<h4 id="3、实例化对象的方式有几种？"><a href="#3、实例化对象的方式有几种？" class="headerlink" title="3、实例化对象的方式有几种？"></a>3、实例化对象的方式有几种？</h4><ul>
<li>用new语句创建对象，这是最常见的创建对象的方法。</li>
<li>通过工厂方法返回对象，如：String str = String.valueOf(23); </li>
<li>运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。如：Object obj = Class.forName(“java.lang.Object”).newInstance(); </li>
<li>调用对象的clone()方法。</li>
<li>通过I/O流（包括反序列化），如运用反序列化手段，调用java.io.ObjectInputStream对象的 readObject()方法。</li>
</ul>
<h4 id="4、由Object类的clone方法引申到深复制和浅复制的区别"><a href="#4、由Object类的clone方法引申到深复制和浅复制的区别" class="headerlink" title="4、由Object类的clone方法引申到深复制和浅复制的区别"></a>4、由Object类的clone方法引申到深复制和浅复制的区别</h4><ul>
<li><a href="https://blog.csdn.net/one_Jachen/article/details/78246047" target="_blank" rel="noopener">Object类之clone()方法详解</a></li>
</ul>
<h4 id="5、反射的概念、用法、实践"><a href="#5、反射的概念、用法、实践" class="headerlink" title="5、反射的概念、用法、实践"></a>5、反射的概念、用法、实践</h4><ul>
<li><a href="https://blog.csdn.net/qq_38777614/article/details/80904894" target="_blank" rel="noopener">反射的概念、用法、实践</a></li>
</ul>
<h4 id="6、Java内存模型和JVM内存结构"><a href="#6、Java内存模型和JVM内存结构" class="headerlink" title="6、Java内存模型和JVM内存结构"></a>6、Java内存模型和JVM内存结构</h4><ul>
<li><a href="https://blog.csdn.net/weixin_40321672/article/details/84778940" target="_blank" rel="noopener">jvm内存模型和java内存模型</a><br>Java内存模型：每个线程有自己的工作内存，同时多个线程共享主内存</li>
</ul>
<h4 id="7、有一台4核8G的机器，该给JVM里的堆区和虚拟机栈分配多大的内存？（初始值、最大值、堆区年轻代和老年代的分配比例等等）"><a href="#7、有一台4核8G的机器，该给JVM里的堆区和虚拟机栈分配多大的内存？（初始值、最大值、堆区年轻代和老年代的分配比例等等）" class="headerlink" title="7、有一台4核8G的机器，该给JVM里的堆区和虚拟机栈分配多大的内存？（初始值、最大值、堆区年轻代和老年代的分配比例等等）"></a>7、有一台4核8G的机器，该给JVM里的堆区和虚拟机栈分配多大的内存？（初始值、最大值、堆区年轻代和老年代的分配比例等等）</h4><ul>
<li>堆区尽量接近8G，同时考虑可能使用的线程数（一般每个虚拟机栈为1m）  </li>
<li>新生代/老年代=3/8，结合实际运行情况，对象年龄的分布  </li>
</ul>
<h4 id="8、堆内存中的年轻代分配内存过少或过多分别有什么影响？复制算法会导致Stop-the-World吗？"><a href="#8、堆内存中的年轻代分配内存过少或过多分别有什么影响？复制算法会导致Stop-the-World吗？" class="headerlink" title="8、堆内存中的年轻代分配内存过少或过多分别有什么影响？复制算法会导致Stop-the-World吗？"></a>8、堆内存中的年轻代分配内存过少或过多分别有什么影响？复制算法会导致Stop-the-World吗？</h4><p>过少：新生代GC频繁<br>过多：老年代GC频繁</p>
<p>Stop-the-World：是为了在枚举根节点的过程中，对象引用关系不可以再改变，所以只要有枚举根节点这一操作，就必须Stop-the-World</p>
<h4 id="9、哪些参数可以设置JVM中的内存分配？"><a href="#9、哪些参数可以设置JVM中的内存分配？" class="headerlink" title="9、哪些参数可以设置JVM中的内存分配？"></a>9、哪些参数可以设置JVM中的内存分配？</h4><ul>
<li>-Xms:n</li>
<li>-Xmx:n</li>
<li>-XX:NewSize=n</li>
<li>-XX:NewRatio=n</li>
<li>-XX:SurvivorRatio=n</li>
<li>-XX:MaxPermSize=n</li>
</ul>
<p><a href="https://xiaoawo.github.io/2020/05/29/JVM-调优/" target="_blank" rel="noopener"><strong>7,8,9详细</strong></a></p>
<h4 id="10、需要在线程范围内去共享一个变量，怎么实现？ThreadLocal源码实现、Key弱引用导致的内存泄露、怎么避免？-（这道题我一直理解成在多个线程之间去共享变量，说了volatile，面试官一直说不对，后来我猜意识到是在线程范围内共享变量…-）"><a href="#10、需要在线程范围内去共享一个变量，怎么实现？ThreadLocal源码实现、Key弱引用导致的内存泄露、怎么避免？-（这道题我一直理解成在多个线程之间去共享变量，说了volatile，面试官一直说不对，后来我猜意识到是在线程范围内共享变量…-）" class="headerlink" title="10、需要在线程范围内去共享一个变量，怎么实现？ThreadLocal源码实现、Key弱引用导致的内存泄露、怎么避免？     （这道题我一直理解成在多个线程之间去共享变量，说了volatile，面试官一直说不对，后来我猜意识到是在线程范围内共享变量….）"></a>10、需要在线程范围内去共享一个变量，怎么实现？ThreadLocal源码实现、Key弱引用导致的内存泄露、怎么避免？     （这道题我一直理解成在多个线程之间去共享变量，说了volatile，面试官一直说不对，后来我猜意识到是在线程范围内共享变量….）</h4><ul>
<li><a href="https://xiaoawo.github.io/2020/05/29/JAVA多线程-线程间通信/" target="_blank" rel="noopener">线程间通信</a></li>
</ul>
<h4 id="11、volatile的作用、实现机制、缓存一致性实现"><a href="#11、volatile的作用、实现机制、缓存一致性实现" class="headerlink" title="11、volatile的作用、实现机制、缓存一致性实现"></a>11、volatile的作用、实现机制、缓存一致性实现</h4><ul>
<li><a href="https://www.jianshu.com/p/9abb4a23ab05" target="_blank" rel="noopener">volatile</a></li>
</ul>
<h4 id="12、AtomicInteger原子类的作用、源码实现机制"><a href="#12、AtomicInteger原子类的作用、源码实现机制" class="headerlink" title="12、AtomicInteger原子类的作用、源码实现机制"></a>12、AtomicInteger原子类的作用、源码实现机制</h4><ul>
<li><a href="https://xiaoawo.github.io/2020/05/29/JAVA多线程-原子类/" target="_blank" rel="noopener">原子类</a></li>
</ul>
<h4 id="13、CAS无锁算法概念、源码实现机制、Unsafe类源码延伸到HotSpot虚拟机对应的C-方法再延伸对应的汇编函数"><a href="#13、CAS无锁算法概念、源码实现机制、Unsafe类源码延伸到HotSpot虚拟机对应的C-方法再延伸对应的汇编函数" class="headerlink" title="13、CAS无锁算法概念、源码实现机制、Unsafe类源码延伸到HotSpot虚拟机对应的C++方法再延伸对应的汇编函数"></a>13、CAS无锁算法概念、源码实现机制、Unsafe类源码延伸到HotSpot虚拟机对应的C++方法再延伸对应的汇编函数</h4><ul>
<li>貌似和12差不多</li>
</ul>
<h4 id="14、ReentrantLock中非公平锁的源码实现、AQS源码实现、为什么需要自旋锁？锁膨胀的过程？"><a href="#14、ReentrantLock中非公平锁的源码实现、AQS源码实现、为什么需要自旋锁？锁膨胀的过程？" class="headerlink" title="14、ReentrantLock中非公平锁的源码实现、AQS源码实现、为什么需要自旋锁？锁膨胀的过程？"></a>14、ReentrantLock中非公平锁的源码实现、AQS源码实现、为什么需要自旋锁？锁膨胀的过程？</h4><ul>
<li><a href="https://mp.weixin.qq.com/s?__biz=MzI0MzI1Mjg5Nw==&mid=2247483689&idx=1&sn=4bd727cc4991e54e273e099010c82d3b&chksm=e96eaae7de1923f14db6ab744331c5f3ea1176af0cfd16df598f9e8817f2e4512dae6dd17d16&token=860755966&lang=zh_CN&scene=21#wechat_redirect" target="_blank" rel="noopener">Synchronized1</a></li>
<li><a href="https://xiaoawo.github.io/2020/05/29/JAVA多线程-ReentrantLock/" target="_blank" rel="noopener">ReentrantLock</a></li>
<li><a href="https://segmentfault.com/a/1190000017372067" target="_blank" rel="noopener">AQS</a></li>
<li>自旋锁，认为知道当前线程自旋一小会，就可以获取到锁了，而自旋引起的开销，相比于重量级锁，无疑小了很多</li>
</ul>
<h4 id="15、线程池的使用场景、常用参数、拒绝策略"><a href="#15、线程池的使用场景、常用参数、拒绝策略" class="headerlink" title="15、线程池的使用场景、常用参数、拒绝策略"></a>15、线程池的使用场景、常用参数、拒绝策略</h4><ul>
<li><a href="https://www.jianshu.com/p/7726c70cdc40" target="_blank" rel="noopener">优势及工作原理</a></li>
<li><a href="https://www.cnblogs.com/CarpenterLee/p/9558026.html" target="_blank" rel="noopener">使用</a></li>
<li><a href="https://www.jianshu.com/p/71b5e40f94e0" target="_blank" rel="noopener">应用场景</a></li>
</ul>
<h4 id="16、阻塞队列的种类、底层数据结构和使用场景"><a href="#16、阻塞队列的种类、底层数据结构和使用场景" class="headerlink" title="16、阻塞队列的种类、底层数据结构和使用场景"></a>16、阻塞队列的种类、底层数据结构和使用场景</h4><ul>
<li><a href="https://blog.csdn.net/littlewhitevg/article/details/105623362" target="_blank" rel="noopener"><strong>阻塞队列</strong></a></li>
</ul>
<h4 id="17、手写BIO的Socket编程、BIO和NIO的区别"><a href="#17、手写BIO的Socket编程、BIO和NIO的区别" class="headerlink" title="17、手写BIO的Socket编程、BIO和NIO的区别"></a>17、手写BIO的Socket编程、BIO和NIO的区别</h4><h4 id="18、Netty线程模型、零拷贝、粘包拆包、心跳机制、Pipeline源码"><a href="#18、Netty线程模型、零拷贝、粘包拆包、心跳机制、Pipeline源码" class="headerlink" title="18、Netty线程模型、零拷贝、粘包拆包、心跳机制、Pipeline源码"></a>18、Netty线程模型、零拷贝、粘包拆包、心跳机制、Pipeline源码</h4><h4 id="19、责任链模型、策略模式、模板模式、设计模式里的原则"><a href="#19、责任链模型、策略模式、模板模式、设计模式里的原则" class="headerlink" title="19、责任链模型、策略模式、模板模式、设计模式里的原则"></a>19、责任链模型、策略模式、模板模式、设计模式里的原则</h4><p>20、Top K问题，找到上千万个数字中从大到小的前10个数字<br>21、MySQL中的聚集索引和稀疏索引区别、索引是越多越好吗？什么样的字段适合建索引？<br>22、索引覆盖和回表的概念、怎么避免回表？<br>23、为什么采用B+树而不用AVL树？<br>24、事务的底层实现<br>25、MVCC的概念及实现机制<br>26、Redis为什么这么快？为什么不用多线程？<br>27、哈希表查询的时间复杂度、哈希冲突的解决方法？<br>28、Sorted Set的应用场景、跳表的实现、查询和插入的时间复杂度？<br>29、Dubbo的应用场景、底层通信组件、服务降级、负载均衡、接口暴露、序列化方式、让你实现一个简单的RPC框架你会怎么做？<br>30、Zookeeper的应用场景、watch机制、领导者选举算法、ZK实现分布式锁<br>31、对称加密、非对称加密、数字证书、HTTPS的连接过程、SSL加密一定安全吗？SSL在哪一层实现加密？<br>32、OSI七层协议？路由器工作在那一层？HTTP、TCP、FTP、DNS工作在哪一层？<br>33、ARP协议的作用及流程<br>34、Git的操作、代码冲突的解决方法<br>35、Redis的缓存穿透、缓存雪崩、数据一致性的解决方案<br>36、Elasticsearch的倒排索引、index和document的概念、脑裂问题<br>37、RabbitMQ应用场景、生产/消费者和发布/订阅模式概念和应用、数据丢失问题<br>38、商品超卖的解决方法、MySQL乐观锁和Redis乐观锁<br>39、手写SQL：有一个成绩表，表里有三个字段分别是姓名、课程和成绩，求课程平均分大于85分的学生姓名和平均成绩。<br>40、算法：写归并排序和快排、分析时间复杂度、怎么评定是不是一个稳定的排序算法？<br>二面（视频面） 50分钟<br>1、Hashmap和Concurrenthashmap<br>2、线程池核心参数、拒绝策略<br>3、SynchroQueue的应用场景？ 可以存几个元素？<br>4、Lock的公平锁和非公平锁的怎么实现的<br>5、说说AQS<br>6、Lock是怎么给线程分配锁的？<br>7、Spring Bean的生命周期<br>8、说一说Spring的AOP<br>9、SpringBoot启动过程的源码<br>10、怎么学习开源框架<br>11、Netty零拷贝？心跳机制？粘包拆包？<br>12、ASM怎么实现cglib<br>13、说一说数据库有哪些索引？聚簇索引和非聚簇索引区别？什么是索引覆盖和回表？什么是索引下推？<br>14、二叉树和B+树的区别<br>15、了解哪些常用的Linux命令<br>16、Linux根目录下有哪些文件夹<br>17、JVM常用命令<br>18、jstat的常用参数<br>19、进程通信方式<br>20、Linux线程调度方式<br>21、Linux的缓存有几级<br>22、Redis的删除策略？<br>22、什么是分布式？分布式和微服务有什么联系？CAP理论听过吗？为什么CAP理论最多职能满足两个？<br>23、算法：环形链表入口<br>HR面（电话面） 18分钟     没有自我介绍，直入主题。<br>1、你觉得笔试难度怎么样？<br>2、我看你前几轮的综合成绩都蛮高的，未来想在北京发展吗？<br>3、像广州深圳杭州互联网公司都很多，为什么投了北京的岗位呢？<br>4、我可能比较直白一点，你的学历在我们这些候选人里面是比较低的，你觉得你的优势在哪里？<br>5、想过考研吗？不考研的话未来可能几年后你觉得有能力能胜任这些工作吗？<br>6、你觉得为什么自己没有上一些比较好的学校？专业是自己选的吗？<br>7、实习时长？给前两轮面试官一个评价？</p>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/05/28/MySQL-SQL/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="小蜗">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/xiaoawo.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="小蜗学习之旅">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2020/05/28/MySQL-SQL/" itemprop="url">MySQL-SQL</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-05-28T20:48:36+08:00">
                2020-05-28
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/MySQL/" itemprop="url" rel="index">
                    <span itemprop="name">-MySQL</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="SQL"><a href="#SQL" class="headerlink" title="SQL"></a>SQL</h2><h3 id="说明：SQL的语法详见《MYSQL必知必会》，这里只做一些问题的归类"><a href="#说明：SQL的语法详见《MYSQL必知必会》，这里只做一些问题的归类" class="headerlink" title="说明：SQL的语法详见《MYSQL必知必会》，这里只做一些问题的归类"></a>说明：SQL的语法详见《MYSQL必知必会》，这里只做一些问题的归类</h3><ul>
<li><a href="https://www.cnblogs.com/yyxz/p/3812499.html" target="_blank" rel="noopener"><strong>left join语句的作用，后面on和where的区别</strong></a>  <ul>
<li>左边表做全表扫描，on只对右边表起过滤作用，where对两个表都起过滤作用</li>
</ul>
</li>
</ul>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
  </section>

  
  <nav class="pagination">
    <span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="page-number" href="/page/3/">3</a><a class="extend next" rel="next" href="/page/2/">&lt;i class&#x3D;&quot;fa fa-angle-right&quot;&gt;&lt;&#x2F;i&gt;</a>
  </nav>



          </div>
          


          

        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      

      <section class="site-overview-wrap sidebar-panel sidebar-panel-active">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image"
                src="/images/xiaoawo.jpg"
                alt="小蜗" />
            
              <p class="site-author-name" itemprop="name">小蜗</p>
              <p class="site-description motion-element" itemprop="description">凡心所向，素履所往，生如逆旅，一苇以航</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/%7C%7C%20archive">
              
                  <span class="site-state-item-count">25</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/categories/index.html">
                  <span class="site-state-item-count">9</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">小蜗</span>

  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Gemini</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  


  



  
  









  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  

  
  
    <script type="text/javascript" src="/lib/canvas-nest/canvas-nest.min.js"></script>
  

  
  
    <script type="text/javascript" src="/lib/three/three.min.js"></script>
  

  
  
    <script type="text/javascript" src="/lib/three/three-waves.min.js"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>



  

  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
